// gcc -o test_worker_plus test_worker_plus.c
#define MAX_LEN_OF_COMMEND 255

#define RELABLE_SYSCALL_NUM 4294967290
#define DOWNGRADE_SYSCALL_NUM 4294967288

#include <sys/syscall.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include<string.h>


int opt_read(const char * filename){
    //char filename[256];
    FILE *file;
    // 尝试打开文件
    file = fopen(filename, "r"); // 以只读模式打开文件
    if (file == NULL) {
        // 如果文件打开失败，打印错误信息并退出程序
        perror("文件打开失败");
        return EXIT_FAILURE;
    }
    // 读取并打印文件内容
    char ch;
    while ((ch = fgetc(file)) != EOF) { // 读取文件直到文件末尾
        putchar(ch); // 打印字符
    }
    // 关闭文件
    fclose(file);
    printf("\n文件内容已打印完毕。\n");
    return 1;
}

int opt_write(const char * filename, const char * write_what){
    //char filename[256];
    //char write_what[256];
    FILE *file;
    // 尝试打开文件
    file = fopen(filename, "a"); // 以只读模式打开文件
    if (file == NULL) {
        // 如果文件打开失败，打印错误信息并退出程序
        perror("文件打开失败");
        return EXIT_FAILURE;
    }
    // 写入文件
    printf("写入 %s 完毕。\n", write_what);
    fputs(write_what, file);
    // 关闭文件
    fclose(file);

    return 1;
}

int opt__relable(int need_change_class_id, _Bool is_add, int op_what_id){
    int tmp = is_add;
    syscall(SYS_write, RELABLE_SYSCALL_NUM, need_change_class_id, tmp, op_what_id);
    return 0;
}

int opt_downgrade(int need_change_class_id, int add_what_id){
    syscall(SYS_write, DOWNGRADE_SYSCALL_NUM, need_change_class_id, add_what_id);
    return 0;
}

int opt_create_file(const char * create_what){
    FILE *fp;
	fp = fopen(create_what,"w+"); // 创建名为test.c文件,"w+"该文件可读可写
    fprintf(fp,"%s","Hello \n");
	return 1;
}

int opt_remove_file(const char * remove_what){
    if(remove(remove_what) == 0) {
        printf("文件删除成功\n");
    } else {
        perror("删除文件失败");
    }
    return 0;
}

int opt_creat_and_write_fifo(const char * fifo_name, const char * write_what){
   // 创建并写入命名管道
   if (mkfifo(fifo_name, 0666) == -1) {
       perror("mkfifo");
       exit(1);
   }
   int write_fd = open(fifo_name, O_WRONLY);
   if (write_fd == -1) {
       perror("open for write");
       exit(1);
   }
   write(write_fd, write_what, strlen(write_what));
   close(write_fd);
}

int opt_read_fifo(const char * fifo_name){
    // 读取命名管道
    int read_fd = open(fifo_name, O_RDONLY);
    if (read_fd == -1) {
        perror("open for read");
        exit(1);
    }
    char read_buf[128];
    read(read_fd, read_buf, sizeof(read_buf) - 1);
    read_buf[sizeof(read_buf) - 1] = '\0'; // 确保字符串以空字符结尾
    printf("Read from FIFO: %s\n", read_buf);
    close(read_fd);
}

int do_one_line(const char *line_contents){
    char *commend_type = malloc(60);
    char *tmp_str = malloc(MAX_LEN_OF_COMMEND);
    char *tmp_str1 = malloc(MAX_LEN_OF_COMMEND);
    int opn1, opn2;

    if (line_contents[0]=='#')
        return 1;
    printf(" > %s \n", line_contents);
    sscanf(line_contents, "%s", commend_type);

    if (strcmp(commend_type, "new") == 0){
        sscanf(line_contents, "new %s", tmp_str);
        printf("创建文件: %s\n", tmp_str);
        opt_create_file(tmp_str);
    }
    else if (strcmp(commend_type, "remove") == 0){
        printf("删除文件: %s\n", tmp_str);
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_remove_file(tmp_str);
    }
    else if (strcmp(commend_type, "read") == 0){
        printf("读文件: %s\n", tmp_str);
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_read(tmp_str);
    }
    else if (strcmp(commend_type, "write") == 0){
        sscanf(line_contents, "%*s %s %s", tmp_str, tmp_str1);
        opt_write(tmp_str, tmp_str1);
    }
    else if (strcmp(commend_type, "downgrade") == 0){
        sscanf(line_contents, "%*s %d %d", &opn1, &opn2);
        opt_downgrade(opn1, opn2);
        // printf("执行完成，但不知道是否成功，可通过查看访问控制日志来确认执行结果\n");
    }
    else if (strcmp(commend_type, "relabe_add") == 0){
        sscanf(line_contents, "%*s %d %d", &opn1, &opn2);
        opt__relable(opn1, 1, opn2);
        printf("执行完成，但不知道是否成功，可通过查看访问控制日志来确认执行结果\n");
    }
    else if (strcmp(commend_type, "relabe_remove") == 0){
        sscanf(line_contents, "%*s %d %d", &opn1, &opn2);
        opt__relable(opn1, 0, opn2);
        // printf("执行完成，但不知道是否成功，可通过查看访问控制日志来确认执行结果\n");
    }
    else if (strcmp(commend_type, "fifo_create_and_write") == 0){
        sscanf(line_contents, "%*s %s %s", tmp_str, tmp_str1);
        opt_creat_and_write_fifo(tmp_str, tmp_str1);
    }
    else if (strcmp(commend_type, "fifo_read") == 0){
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_read_fifo(tmp_str);
    }
    else if (strcmp(commend_type, "exit") == 0){
        exit(EXIT_SUCCESS);
    }
    return 1;
}

int main(int argc, char *argv[]) {
    const char *filename = "test_commend.txt";
    if (argc == 2)
        filename = argv[1];
    FILE *in_file = fopen(filename, "r");

    struct stat sb;
    stat(filename, &sb);
    char *line_contents = malloc(sb.st_size);


    while (fscanf(in_file, "%[^\n] ", line_contents) != EOF) {
        print("%s",line_contents);
        do_one_line(line_contents);
    }
    fclose(in_file);
    exit(EXIT_SUCCESS);
}